﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ComponentModel;
using System.IO;
using System.Collections.ObjectModel;

namespace FamilyShowSource.Models
{
    /// <summary>
    /// Presents a photo associated with a Person class
    /// </summary>
    public class Photo : INotifyPropertyChanged
    {
        #region Fields

        /// <summary>
        /// The relative path to the photo file
        /// </summary>
        private string relativePath;

        /// <summary>
        /// Determinate specified photo is avatar
        /// </summary>
        private bool isAvatar;

        /// <summary>
        /// Raise event when property has changed on a component
        /// </summary>
        public event PropertyChangedEventHandler PropertyChanged;

        /// <summary>
        /// The constants specific to this class
        /// </summary>
        public static class Const
        {
            /// <summary>
            /// Name of the folder which contains photos
            /// </summary>
            public const string PhotosFolderName = "Images";
        }

        #endregion

        #region Properties

        /// <summary>
        /// The relative path to the photo.
        /// </summary>
        public string RelativePath
        {
            get { return this.relativePath; }
            set
            {
                if (this.relativePath != value)
                {
                    this.relativePath = value;
                    this.OnPropertyChanged("RelativePath");
                }
            }
        }

        /// <summary>
        /// The fully qualified path to the photo.
        /// </summary>
        public string AbsolutePath
        {
            get
            {
                string tempFolder = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData),
                    App.ApplicationFolderName);
                tempFolder = Path.Combine(tempFolder, App.AppDataFolderName);

                if (this.relativePath != null)
                    return Path.Combine(tempFolder, relativePath);
                else
                    return string.Empty;
            }
        }

        /// <summary>
        /// Determinate whether a photo is avatar
        /// </summary>
        public bool IsAvatar
        {
            get { return this.isAvatar; }
            set
            {
                if (this.isAvatar != value)
                {
                    this.isAvatar = value;
                    this.OnPropertyChanged("IsAvatar");
                }
            }
        }

        #endregion

        #region Constructors

        /// <summary>
        /// Empty constructor is needed for serialization
        /// </summary>
        public Photo() { }

        #endregion

        #region Methods

        /// <summary>
        /// Copies the photo file to the application photos folder. 
        /// Returns the relative path to the copied photo.
        /// </summary>
        private void Copy(string fileName)
        {
            // The photo file being copied
            FileInfo fi = new FileInfo(fileName);

            // Absolute path to the application folder
            string appLocation = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData),
                App.ApplicationFolderName);
            appLocation = Path.Combine(appLocation, App.AppDataFolderName);

            // Absolute path to the photos folder
            string photoLocation = Path.Combine(appLocation, Const.PhotosFolderName);

            // Fully qualified path to the new photo file
            string photoFullPath = Path.Combine(photoLocation, fi.Name);

            // Relative path to the new photo file
            string photoRelLocation = Path.Combine(Const.PhotosFolderName, fi.Name);

            // Create the appLocation directory if it doesn't exist
            if (!Directory.Exists(appLocation))
                Directory.CreateDirectory(appLocation);

            // Create the photos directory if it doesn't exist
            if (!Directory.Exists(photoLocation))
                Directory.CreateDirectory(photoLocation);

            // Copy the photo.
            try
            {
                // Store the relative path to the story
                this.relativePath = photoRelLocation;
                fi.CopyTo(photoFullPath, true);
            }
            catch
            {
                // Could not copy the photo. Handle all exceptions 
                // the same, ignore and continue.
            }
        }

        /// <summary>
        /// Delete the person's story if it exists
        /// </summary>
        public void Delete()
        {
            try
            {
                File.Delete(this.AbsolutePath);
            }
            catch
            {
                // Could not delete the file. Handle all exceptions
                // the same, ignore and continue.
            }
        }

        /// <summary>
        /// Raised event when the propety has changed on a component
        /// </summary>
        /// <param name="propertyName"></param>
        private void OnPropertyChanged(string propertyName)
        {
            if (this.PropertyChanged != null)
                this.PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
        }

        #endregion
    }

    /// <summary>
    /// Collection for photos.
    /// </summary>
    public class PhotoCollection : ObservableCollection<Photo> { }
}
